package org.mm.proxycache.http.codec;

import org.apache.mina.common.IoBuffer;
import org.apache.mina.common.IoSession;
import org.apache.mina.filter.codec.ProtocolDecoderAdapter;
import org.apache.mina.filter.codec.ProtocolDecoderException;
import org.apache.mina.filter.codec.ProtocolDecoderOutput;
import org.mm.proxycache.http.HttpRequest;
import org.mm.proxycache.http.codec.HttpParser.ParserStatus;
import org.mm.proxycache.http.codec.HttpParser.ParserType;

public class HttpRequestDecoder extends ProtocolDecoderAdapter
{

    /*
     * (non-Javadoc)
     * 
     * @see org.apache.mina.filter.codec.ProtocolDecoder#decode(org.apache.mina.common.IoSession,
     *      org.apache.mina.common.IoBuffer,
     *      org.apache.mina.filter.codec.ProtocolDecoderOutput)
     */
    public void decode( IoSession session, IoBuffer in, ProtocolDecoderOutput out )
            throws Exception
    {
        HttpParser parser = (HttpParser) session.getAttribute( DecoderName );
        if ( parser == null )
        {
            parser = new HttpParser( ParserType.RequestParser );
            session.setAttributeIfAbsent( DecoderName, parser );
        }

        ParserStatus res = parser.decode( in );
        switch ( res )
        {
        case Error:
            throw new ProtocolDecoderException( "Error parsing HTTP request" );

        case Done:
        case NeedData:
            while ( true )
            {
                Object obj = parser.getParsed();
                if ( obj == null )
                    break;

                if ( obj instanceof HttpRequest )
                {
                    HttpRequest request = (HttpRequest) obj;
                    setRequest( session, request );
                }

                out.write( obj );
            }
            break;

        default:
            break;
        }

        if ( res == ParserStatus.Done )
            parser.reset();
    }

    public static HttpRequest getRequest( IoSession session )
    {
        return (HttpRequest) session.getAttribute( RequestMessage );
    }

    private static void setRequest( IoSession session, HttpRequest request )
    {
        session.setAttribute( RequestMessage, request );
    }

    // ////////////////////////////////////

    private static final String RequestMessage = HttpRequestDecoder.class.getName()
            + ".requestMessage";

    private static final String DecoderName = HttpRequestDecoder.class.getName();

}
